package edu.yctc.weblog.service.impl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import edu.yctc.weblog.constant.ResultCode;
import edu.yctc.weblog.dao.CommentDAO;
import edu.yctc.weblog.entity.CommentDO;
import edu.yctc.weblog.entity.PageDO;
import edu.yctc.weblog.entity.ResultDO;
import edu.yctc.weblog.enums.CommentStatus;
import edu.yctc.weblog.service.CommentService;
import edu.yctc.weblog.utils.PageQueryUtil;

@Service("commentService")
public class CommentServiceImpl implements CommentService {

    private final static Logger LOG = LoggerFactory.getLogger("serviceLogger");

    @Resource
    private CommentDAO commentDAO;

    @Override
    @Transactional
    public ResultDO<Void> addComment(CommentDO commentDO) {
        commentDAO.comment(commentDO);
        LOG.info("add comment success, commentDO={}", commentDO);
        return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
    }

    @Override
    public ResultDO<PageDO> getCommentsPage(PageQueryUtil pageQueryUtil) {
        List<CommentDO> commentDOs = commentDAO.getBlogCommentList(pageQueryUtil);
        int total = commentDAO.getTotalBlogComments(pageQueryUtil);
        PageDO pageDO = new PageDO(total, pageQueryUtil.getLimit(), pageQueryUtil.getPage(), commentDOs);
        LOG.info("get comments page success, pageDO={}", pageDO);
        return new ResultDO<PageDO>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, pageDO);
    }

    @Override
    public ResultDO<Integer> getTotalComments() {
        return new ResultDO<Integer>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS,
            commentDAO.getTotalBlogComments(null));
    }

    @Override
    @Transactional
    public ResultDO<Void> checkDone(Long[] ids) {
        for (Long id : ids) {
            if (id <= 0) {
                LOG.error("check done comments fail, parameter invalid, id={}", id);
                return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID);
            }
        }
        commentDAO.checkDone(ids);
        LOG.info("check done comments success, ids={}", Arrays.asList(ids));
        return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
    }

    @Override
    @Transactional
    public ResultDO<Void> deleteBatch(Long[] ids) {
        for (Long id : ids) {
            if (id <= 0) {
                LOG.error("delete comments fail, parameter invalid, id={}", id);
                return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID);
            }
        }
        commentDAO.deleteBatch(ids);
        LOG.info("delete comments success, ids={}", Arrays.asList(ids));
        return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
    }

    @Override
    @Transactional
    public ResultDO<Void> reply(Long commentId, String replyBody) {
        if (commentId <= 0) {
            LOG.error("reply comment fail, parameter invalid, commentId={}, reply={}", commentId, replyBody);
            return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID);
        }
        // comment需不为空且已审核
        CommentDO commentDO = commentDAO.getCommentDOById(commentId);
        if (commentDO != null && commentDO.getStatus().intValue() == CommentStatus.REVIEWED) {
            commentDO.setReply(replyBody);
            commentDAO.reply(commentDO);
            LOG.info("reply comment success, commentDO={}", commentDO);
        } else {
            LOG.error("reply comment fail, commentDO={}", commentDO);
            return new ResultDO<>(false, ResultCode.DB_ERROR, ResultCode.MSG_DB_ERROR);
        }
        return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
    }

    @Override
    public ResultDO<PageDO> getCommentPageByBlogIdAndPageNum(Long blogId, int page) {
        if (blogId <= 0 || page < 1) {
            LOG.error("get comment page by blogId and page fail, parameter invalid, blogId={}, page={}", blogId, page);
            return new ResultDO<PageDO>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
        }
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("page", page);
        params.put("limit", 8);
        params.put("blogId", blogId);
        params.put("commentStatus", CommentStatus.REVIEWED);
        PageQueryUtil pageQueryUtil = new PageQueryUtil(params);
        List<CommentDO> commentDOs = commentDAO.getBlogCommentList(params);
        if (CollectionUtils.isEmpty(commentDOs) == false) {
            int total = commentDAO.getTotalBlogComments(params);
            PageDO pageDO = new PageDO(total, pageQueryUtil.getLimit(), pageQueryUtil.getPage(), commentDOs);
            LOG.info("get comment page by blogId and page success, blogId={}, pageDO={}", blogId, pageDO);
            return new ResultDO<PageDO>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, pageDO);
        }
        LOG.error("get comment page by blogId and page fail, no commentDOs, blogId={}", blogId);
        return new ResultDO<PageDO>(false, ResultCode.DB_ERROR, ResultCode.MSG_DB_ERROR, null);
    }

}
